home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / cc-mode / cc-cmds.el.z / cc-cmds.el
Encoding:
Text File  |  1998-05-21  |  55.2 KB  |  1,629 lines

  1. ;;; cc-cmds.el --- user level commands for CC Mode 
  2.  
  3. ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
  4.  
  5. ;; Authors:    1992-1997 Barry A. Warsaw
  6. ;;             1987 Dave Detlefs and Stewart Clamen
  7. ;;             1985 Richard M. Stallman
  8. ;; Maintainer: cc-mode-help@python.org
  9. ;; Created:    22-Apr-1997 (split from cc-mode.el)
  10. ;; Version:    See cc-mode.el
  11. ;; Keywords:   c languages oop
  12.  
  13. ;; This file is part of GNU Emacs.
  14.  
  15. ;; GNU Emacs is free software; you can redistribute it and/or modify
  16. ;; it under the terms of the GNU General Public License as published by
  17. ;; the Free Software Foundation; either version 2, or (at your option)
  18. ;; any later version.
  19.  
  20. ;; GNU Emacs is distributed in the hope that it will be useful,
  21. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. ;; GNU General Public License for more details.
  24.  
  25. ;; You should have received a copy of the GNU General Public License
  26. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  27. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  28. ;; Boston, MA 02111-1307, USA.
  29.  
  30. (eval-when-compile
  31.   (require 'cc-defs))
  32.  
  33.  
  34. (defun c-calculate-state (arg prevstate)
  35.   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
  36.   ;; arg is nil or zero, toggle the state. If arg is negative, turn
  37.   ;; the state off, and if arg is positive, turn the state on
  38.   (if (or (not arg)
  39.       (zerop (setq arg (prefix-numeric-value arg))))
  40.       (not prevstate)
  41.     (> arg 0)))
  42.  
  43. ;; Auto-newline and hungry-delete
  44. (defun c-toggle-auto-state (arg)
  45.   "Toggle auto-newline feature.
  46. Optional numeric ARG, if supplied turns on auto-newline when positive,
  47. turns it off when negative, and just toggles it when zero.
  48.  
  49. When the auto-newline feature is enabled (as evidenced by the `/a' or
  50. `/ah' on the modeline after the mode name) newlines are automatically
  51. inserted after special characters such as brace, comma, semi-colon,
  52. and colon."
  53.   (interactive "P")
  54.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  55.   (c-update-modeline)
  56.   (c-keep-region-active))
  57.  
  58. (defun c-toggle-hungry-state (arg)
  59.   "Toggle hungry-delete-key feature.
  60. Optional numeric ARG, if supplied turns on hungry-delete when positive,
  61. turns it off when negative, and just toggles it when zero.
  62.  
  63. When the hungry-delete-key feature is enabled (as evidenced by the
  64. `/h' or `/ah' on the modeline after the mode name) the delete key
  65. gobbles all preceding whitespace in one fell swoop."
  66.   (interactive "P")
  67.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  68.   (c-update-modeline)
  69.   (c-keep-region-active))
  70.  
  71. (defun c-toggle-auto-hungry-state (arg)
  72.   "Toggle auto-newline and hungry-delete-key features.
  73. Optional numeric ARG, if supplied turns on auto-newline and
  74. hungry-delete when positive, turns them off when negative, and just
  75. toggles them when zero.
  76.  
  77. See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
  78.   (interactive "P")
  79.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  80.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  81.   (c-update-modeline)
  82.   (c-keep-region-active))
  83.  
  84.  
  85. ;; Electric keys
  86.  
  87. ;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been
  88. ;; separated and "\177" is no longer an alias for both keys.  Also,
  89. ;; the variable delete-key-deletes-forward controls in which direction
  90. ;; the Delete keysym deletes characters.  The functions
  91. ;; c-electric-delete and c-electric-backspace attempt to deal with
  92. ;; this new functionality.  For Emacs 19 and XEmacs 19 backwards
  93. ;; compatibility, the old behavior has moved to c-electric-backspace
  94. ;; and c-backspace-function.
  95.  
  96. (defun c-electric-backspace (arg)
  97.   "Deletes preceding character or whitespace.
  98. If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  99. \"/ah\" string on the mode line, then all preceding whitespace is
  100. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  101. nil, or point is inside a literal then the function in the variable
  102. `c-backspace-function' is called.
  103.  
  104. See also \\[c-electric-delete]."
  105.   (interactive "*P")
  106.   (if (or (not c-hungry-delete-key)
  107.       arg
  108.       (c-in-literal))
  109.       (funcall c-backspace-function (prefix-numeric-value arg))
  110.     (let ((here (point)))
  111.       (skip-chars-backward " \t\n")
  112.       (if (/= (point) here)
  113.       (delete-region (point) here)
  114.     (funcall c-backspace-function 1)
  115.     ))))
  116.  
  117. (defun c-electric-delete (arg)
  118.   "Deletes preceding or following character or whitespace.
  119.  
  120. The behavior of this function depends on the variable
  121. `delete-key-deletes-forward'.  If this variable is nil (or does not
  122. exist, as in older Emacsen), then this function behaves identical to
  123. \\[c-electric-backspace].
  124.  
  125. If `delete-key-deletes-forward' is non-nil and is supported in your
  126. Emacs, then deletion occurs in the forward direction.  So if
  127. `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  128. \"/ah\" string on the mode line, then all following whitespace is
  129. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  130. nil, or point is inside a literal then the function in the variable
  131. `c-delete-function' is called."
  132.   (interactive "*P")
  133.   (if (and (boundp 'delete-key-deletes-forward)
  134.        delete-key-deletes-forward)
  135.       (if (or (not c-hungry-delete-key)
  136.           arg
  137.           (c-in-literal))
  138.       (funcall c-delete-function (prefix-numeric-value arg))
  139.     (let ((here (point)))
  140.       (skip-chars-forward " \t\n")
  141.       (if (/= (point) here)
  142.           (delete-region (point) here)
  143.         (funcall c-delete-function 1))))
  144.     ;; act just like c-electric-backspace
  145.     (c-electric-backspace arg)))
  146.  
  147. (defun c-electric-pound (arg)
  148.   "Electric pound (`#') insertion.
  149. Inserts a `#' character specially depending on the variable
  150. `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if
  151. point is inside a literal, nothing special happens."
  152.   (interactive "*P")
  153.   (if (or (c-in-literal)
  154.       arg
  155.       (not (memq 'alignleft c-electric-pound-behavior)))
  156.       ;; do nothing special
  157.       (self-insert-command (prefix-numeric-value arg))
  158.     ;; place the pound character at the left edge
  159.     (let ((pos (- (point-max) (point)))
  160.       (bolp (bolp)))
  161.       (beginning-of-line)
  162.       (delete-horizontal-space)
  163.       (insert-char last-command-char 1)
  164.       (and (not bolp)
  165.        (goto-char (- (point-max) pos)))
  166.       )))
  167.  
  168. (defun c-electric-brace (arg)
  169.   "Insert a brace.
  170.  
  171. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  172. or \"/ah\" string on the mode line, newlines are inserted before and
  173. after braces based on the value of `c-hanging-braces-alist'.
  174.  
  175. Also, the line is re-indented unless a numeric ARG is supplied, there
  176. are non-whitespace characters present on the line after the brace, or
  177. the brace is inserted inside a literal."
  178.   (interactive "*P")
  179.   (let* ((c-state-cache (c-parse-state))
  180.      (safepos (c-safe-position (point) c-state-cache))
  181.      (literal (c-in-literal safepos)))
  182.     ;; if we're in a literal, or we're not at the end of the line, or
  183.     ;; a numeric arg is provided, or auto-newlining is turned off,
  184.     ;; then just insert the character.
  185.     (if (or literal arg
  186. ;        (not c-auto-newline)
  187.         (not (looking-at "[ \t]*$")))
  188.     (self-insert-command (prefix-numeric-value arg))
  189.       (let* ((syms
  190.           ;; This is the list of brace syntactic symbols that can
  191.           ;; hang.  If any new ones are added to c-offsets-alist,
  192.           ;; they should be added here as well.
  193.           '(class-open class-close defun-open defun-close
  194.         inline-open inline-close
  195.         brace-list-open brace-list-close
  196.         brace-list-intro brace-list-entry
  197.         block-open block-close
  198.         substatement-open statement-case-open
  199.         extern-lang-open extern-lang-close
  200.         namespace-open namespace-close
  201.         ))
  202.         ;; we want to inhibit blinking the paren since this will
  203.         ;; be most disruptive. we'll blink it ourselves later on
  204.         (old-blink-paren blink-paren-function)
  205.         blink-paren-function
  206.         (insertion-point (point))
  207.         delete-temp-newline
  208.         (preserve-p (and (not (bobp))
  209.                  (eq ?\  (char-syntax (char-before)))))
  210.         ;; shut this up too
  211.         (c-echo-syntactic-information-p nil)
  212.         (syntax (progn
  213.               ;; only insert a newline if there is
  214.               ;; non-whitespace behind us
  215.               (if (save-excursion
  216.                 (skip-chars-backward " \t")
  217.                 (not (bolp)))
  218.               (progn (newline)
  219.                  (setq delete-temp-newline t)))
  220.               (self-insert-command (prefix-numeric-value arg))
  221.               ;; state cache doesn't change
  222.               (c-guess-basic-syntax)))
  223.         (newlines (and
  224.                c-auto-newline
  225.                (or (c-lookup-lists syms syntax c-hanging-braces-alist)
  226.                '(ignore before after)))))
  227.     ;; If syntax is a function symbol, then call it using the
  228.     ;; defined semantics.
  229.     (if (and (not (consp (cdr newlines)))
  230.          (functionp (cdr newlines)))
  231.         (let ((c-syntactic-context syntax))
  232.           (setq newlines
  233.             (funcall (cdr newlines) (car newlines) insertion-point))))
  234.     ;; does a newline go before the open brace?
  235.     (if (memq 'before newlines)
  236.         ;; we leave the newline we've put in there before,
  237.         ;; but we need to re-indent the line above
  238.         (let ((pos (- (point-max) (point)))
  239.           (here (point))
  240.           (c-state-cache c-state-cache))
  241.           (forward-line -1)
  242.           ;; we may need to update the cache. this should still be
  243.           ;; faster than recalculating the state in many cases
  244.           (save-excursion
  245.         (save-restriction
  246.           (narrow-to-region here (point))
  247.           (if (and (c-safe (progn (backward-up-list -1) t))
  248.                (memq (char-before) '(?\) ?}))
  249.                (progn (widen)
  250.                   (c-safe (progn (forward-sexp -1) t))))
  251.               (setq c-state-cache
  252.                 (c-hack-state (point) 'open c-state-cache))
  253.             (if (and (car c-state-cache)
  254.                  (not (consp (car c-state-cache)))
  255.                  (<= (point) (car c-state-cache)))
  256.             (setq c-state-cache (cdr c-state-cache))
  257.               ))))
  258.           (let ((here (point))
  259.             (shift (c-indent-line)))
  260.         (setq c-state-cache (c-adjust-state (c-point 'bol) here
  261.                             (- shift) c-state-cache)))
  262.           (goto-char (- (point-max) pos))
  263.           ;; if the buffer has changed due to the indentation, we
  264.           ;; need to recalculate syntax for the current line, but
  265.           ;; we won't need to update the state cache.
  266.           (if (/= (point) here)
  267.           (setq syntax (c-guess-basic-syntax))))
  268.       ;; must remove the newline we just stuck in (if we really did it)
  269.       (and delete-temp-newline
  270.            (save-excursion
  271.          ;; if there is whitespace before point, then preserve
  272.          ;; at least one space.
  273.          (delete-indentation)
  274.          (just-one-space)
  275.          (if (not preserve-p)
  276.              (delete-char -1))))
  277.       ;; since we're hanging the brace, we need to recalculate
  278.       ;; syntax.  Update the state to accurately reflect the
  279.       ;; beginning of the line.  We punt if we cross any open or
  280.       ;; closed parens because its just too hard to modify the
  281.       ;; known state.  This limitation will be fixed in v5.
  282.       (save-excursion
  283.         (let ((bol (c-point 'bol)))
  284.           (if (zerop (car (parse-partial-sexp bol (1- (point)))))
  285.           (setq c-state-cache (c-whack-state bol c-state-cache)
  286.             syntax (c-guess-basic-syntax))
  287.         ;; gotta punt. this requires some horrible kludgery
  288.         (beginning-of-line)
  289.         (makunbound 'c-state-cache)
  290.         (setq c-state-cache (c-parse-state)
  291.               syntax nil))))
  292.       )
  293.     ;; now adjust the line's indentation. don't update the state
  294.     ;; cache since c-guess-basic-syntax isn't called when the
  295.     ;; syntax is passed to c-indent-line
  296.     (let ((here (point))
  297.           (shift (c-indent-line syntax)))
  298.       (setq c-state-cache (c-adjust-state (c-point 'bol) here
  299.                           (- shift) c-state-cache)))
  300.     ;; Do all appropriate clean ups
  301.     (let ((here (point))
  302.           (pos (- (point-max) (point)))
  303.           mbeg mend)
  304.       ;; clean up empty defun braces
  305.       (if (and c-auto-newline
  306.            (memq 'empty-defun-braces c-cleanup-list)
  307.            (eq last-command-char ?\})
  308.            (c-intersect-lists '(defun-close class-close inline-close)
  309.                       syntax)
  310.            (progn
  311.              (forward-char -1)
  312.              (skip-chars-backward " \t\n")
  313.              (eq (char-before) ?\{))
  314.            ;; make sure matching open brace isn't in a comment
  315.            (not (c-in-literal)))
  316.           (delete-region (point) (1- here)))
  317.       ;; clean up brace-else-brace
  318.       (if (and c-auto-newline
  319.            (memq 'brace-else-brace c-cleanup-list)
  320.            (eq last-command-char ?\{)
  321.            (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
  322.            (progn
  323.              (setq mbeg (match-beginning 0)
  324.                mend (match-end 0))
  325.              (= mend here))
  326.            (not (c-in-literal)))
  327.           (progn
  328.         (delete-region mbeg mend)
  329.         (insert "} else {")))
  330.       ;; clean up brace-elseif-brace
  331.       (if (and c-auto-newline
  332.            (memq 'brace-elseif-brace c-cleanup-list)
  333.            (eq last-command-char ?\{)
  334.            (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t)
  335.            (save-excursion
  336.              (goto-char (match-end 0))
  337.              (c-safe (forward-sexp 1))
  338.              (skip-chars-forward " \t\n")
  339.              (setq mbeg (match-beginning 0)
  340.                mend (match-end 0))
  341.              (= here (1+ (point))))
  342.            (not (c-in-literal)))
  343.           (progn
  344.         (delete-region mbeg mend)
  345.         (insert "} else if ")))
  346.       (goto-char (- (point-max) pos))
  347.       )
  348.     ;; does a newline go after the brace?
  349.     (if (memq 'after newlines)
  350.         (progn
  351.           (newline)
  352.           ;; update on c-state-cache
  353.           (let* ((bufpos (- (point) 2))
  354.              (which (if (eq (char-after bufpos) ?{) 'open 'close))
  355.              (c-state-cache (c-hack-state bufpos which c-state-cache)))
  356.         (c-indent-line))))
  357.     ;; blink the paren
  358.     (and (eq last-command-char ?\})
  359.          old-blink-paren
  360.          (save-excursion
  361.            (c-backward-syntactic-ws safepos)
  362.            (funcall old-blink-paren)))
  363.     ))))
  364.       
  365. (defun c-electric-slash (arg)
  366.   "Insert a slash character.
  367.  
  368. Indent the line as a comment, if:
  369.  
  370.   1. The slash is second of a `//' line oriented comment introducing
  371.      token and we are on a comment-only-line, or
  372.  
  373.   2. The slash is part of a `*/' token that closes a block oriented
  374.      comment.
  375.  
  376. If numeric ARG is supplied or point is inside a literal, indentation
  377. is inhibited."
  378.   (interactive "*P")
  379.   (let* ((ch (char-before))
  380.      (indentp (and (not arg)
  381.                (eq last-command-char ?/)
  382.                (or (and (eq ch ?/)
  383.                 (not (c-in-literal)))
  384.                (and (eq ch ?*)
  385.                 (c-in-literal)))
  386.                ))
  387.      ;; shut this up
  388.      (c-echo-syntactic-information-p nil))
  389.     (self-insert-command (prefix-numeric-value arg))
  390.     (if indentp
  391.     (c-indent-line))))
  392.  
  393. (defun c-electric-star (arg)
  394.   "Insert a star character.
  395. If the star is the second character of a C style comment introducing
  396. construct, and we are on a comment-only-line, indent line as comment.
  397. If numeric ARG is supplied or point is inside a literal, indentation
  398. is inhibited."
  399.   (interactive "*P")
  400.   (self-insert-command (prefix-numeric-value arg))
  401.   ;; if we are in a literal, or if arg is given do not re-indent the
  402.   ;; current line, unless this star introduces a comment-only line.
  403.   (if (and (not arg)
  404.        (memq (c-in-literal) '(c))
  405.        (eq (char-before) ?*)
  406.        (save-excursion
  407.          (forward-char -1)
  408.          (skip-chars-backward "*")
  409.          (if (eq (char-before) ?/)
  410.          (forward-char -1))
  411.          (skip-chars-backward " \t")
  412.          (bolp)))
  413.       ;; shut this up
  414.       (let (c-echo-syntactic-information-p)
  415.     (c-indent-line))
  416.     ))
  417.  
  418. (defun c-electric-semi&comma (arg)
  419.   "Insert a comma or semicolon.
  420. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  421. or \"/ah\" string on the mode line, a newline might be inserted.  See
  422. the variable `c-hanging-semi&comma-criteria' for how newline insertion
  423. is determined.
  424.  
  425. When semicolon is inserted, the line is re-indented unless a numeric
  426. arg is supplied, point is inside a literal, or there are
  427. non-whitespace characters on the line following the semicolon."
  428.   (interactive "*P")
  429.   (let* ((lim (c-most-enclosing-brace (c-parse-state)))
  430.      (literal (c-in-literal lim))
  431.      (here (point))
  432.      ;; shut this up
  433.      (c-echo-syntactic-information-p nil))
  434.     (if (or literal
  435.         arg
  436.         (not (looking-at "[ \t]*$")))
  437.     (self-insert-command (prefix-numeric-value arg))
  438.       ;; do some special stuff with the character
  439.       (self-insert-command (prefix-numeric-value arg))
  440.       ;; do all cleanups, reindentations, and newline insertions, but
  441.       ;; only if c-auto-newline is turned on
  442.       (if (not c-auto-newline) nil
  443.     ;; clean ups
  444.     (let ((pos (- (point-max) (point))))
  445.       (if (and (or (and
  446.             (eq last-command-char ?,)
  447.             (memq 'list-close-comma c-cleanup-list))
  448.                (and
  449.             (eq last-command-char ?\;)
  450.             (memq 'defun-close-semi c-cleanup-list)))
  451.            (progn
  452.              (forward-char -1)
  453.              (skip-chars-backward " \t\n")
  454.              (eq (char-before) ?}))
  455.            ;; make sure matching open brace isn't in a comment
  456.            (not (c-in-literal lim)))
  457.           (delete-region (point) here))
  458.       (goto-char (- (point-max) pos)))
  459.     ;; re-indent line
  460.     (c-indent-line)
  461.     ;; check to see if a newline should be added
  462.     (let ((criteria c-hanging-semi&comma-criteria)
  463.           answer add-newline-p)
  464.       (while criteria
  465.         (setq answer (funcall (car criteria)))
  466.         ;; only nil value means continue checking
  467.         (if (not answer)
  468.         (setq criteria (cdr criteria))
  469.           (setq criteria nil)
  470.           ;; only 'stop specifically says do not add a newline
  471.           (setq add-newline-p (not (eq answer 'stop)))
  472.           ))
  473.       (if add-newline-p
  474.           (progn (newline)
  475.              (c-indent-line)))
  476.       )))))
  477.  
  478. (defun c-electric-colon (arg)
  479.   "Insert a colon.
  480.  
  481. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  482. or \"/ah\" string on the mode line, newlines are inserted before and
  483. after colons based on the value of `c-hanging-colons-alist'.
  484.  
  485. Also, the line is re-indented unless a numeric ARG is supplied, there
  486. are non-whitespace characters present on the line after the colon, or
  487. the colon is inserted inside a literal.
  488.  
  489. This function cleans up double colon scope operators based on the
  490. value of `c-cleanup-list'."
  491.   (interactive "*P")
  492.   (let* ((bod (c-point 'bod))
  493.      (literal (c-in-literal bod))
  494.      syntax newlines is-scope-op
  495.      ;; shut this up
  496.      (c-echo-syntactic-information-p nil))
  497.     (if (or literal
  498.         arg
  499.         (not (looking-at "[ \t]*$")))
  500.     (self-insert-command (prefix-numeric-value arg))
  501.       ;; insert the colon, then do any specified cleanups
  502.       (self-insert-command (prefix-numeric-value arg))
  503.       (let ((pos (- (point-max) (point)))
  504.         (here (point)))
  505.     (if (and c-auto-newline
  506.          (memq 'scope-operator c-cleanup-list)
  507.          (eq (char-before) ?:)
  508.          (progn
  509.            (forward-char -1)
  510.            (skip-chars-backward " \t\n")
  511.            (eq (char-before) ?:))
  512.          (not (c-in-literal))
  513.          (not (eq (char-after (- (point) 2)) ?:)))
  514.         (progn
  515.           (delete-region (point) (1- here))
  516.           (setq is-scope-op t)))
  517.     (goto-char (- (point-max) pos)))
  518.       ;; lets do some special stuff with the colon character
  519.       (setq syntax (c-guess-basic-syntax)
  520.         ;; some language elements can only be determined by
  521.         ;; checking the following line.  Lets first look for ones
  522.         ;; that can be found when looking on the line with the
  523.         ;; colon
  524.         newlines
  525.         (and c-auto-newline
  526.          (or (c-lookup-lists '(case-label label access-label)
  527.                      syntax c-hanging-colons-alist)
  528.              (c-lookup-lists '(member-init-intro inher-intro)
  529.                      (prog2
  530.                      (insert "\n")
  531.                      (c-guess-basic-syntax)
  532.                        (delete-char -1))
  533.                      c-hanging-colons-alist))))
  534.       ;; indent the current line
  535.       (c-indent-line syntax)
  536.       ;; does a newline go before the colon?  Watch out for already
  537.       ;; non-hung colons.  However, we don't unhang them because that
  538.       ;; would be a cleanup (and anti-social).
  539.       (if (and (memq 'before newlines)
  540.            (not is-scope-op)
  541.            (save-excursion
  542.          (skip-chars-backward ": \t")
  543.          (not (bolp))))
  544.       (let ((pos (- (point-max) (point))))
  545.         (forward-char -1)
  546.         (newline)
  547.         (c-indent-line)
  548.         (goto-char (- (point-max) pos))))
  549.       ;; does a newline go after the colon?
  550.       (if (and (memq 'after (cdr-safe newlines))
  551.            (not is-scope-op))
  552.       (progn
  553.         (newline)
  554.         (c-indent-line)))
  555.       )))
  556.  
  557. (defun c-electric-lt-gt (arg)
  558.   "Insert a less-than, or greater-than character.
  559. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  560. or \"/ah\" string on the mode line, the line will be re-indented if
  561. the character inserted is the second of a C++ style stream operator
  562. and the buffer is in C++ mode.
  563.  
  564. The line will also not be re-indented if a numeric argument is
  565. supplied, or point is inside a literal."
  566.   (interactive "*P")
  567.   (let ((indentp (and (not arg)
  568.               (eq (char-before) last-command-char)
  569.               (not (c-in-literal))))
  570.     ;; shut this up
  571.     (c-echo-syntactic-information-p nil))
  572.     (self-insert-command (prefix-numeric-value arg))
  573.     (if indentp
  574.     (c-indent-line))))
  575.  
  576.  
  577.  
  578. ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
  579. ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
  580. (defun c-forward-into-nomenclature (&optional arg)
  581.   "Move forward to end of a nomenclature section or word.
  582. With arg, to it arg times."
  583.   (interactive "p")
  584.   (let ((case-fold-search nil))
  585.     (if (> arg 0)
  586.     (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
  587.       (while (and (< arg 0)
  588.           (re-search-backward
  589.            "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
  590.            (point-min) 0))
  591.     (forward-char 1)
  592.     (setq arg (1+ arg)))))
  593.   (c-keep-region-active))
  594.  
  595. (defun c-backward-into-nomenclature (&optional arg)
  596.   "Move backward to beginning of a nomenclature section or word.
  597. With optional ARG, move that many times.  If ARG is negative, move
  598. forward."
  599.   (interactive "p")
  600.   (c-forward-into-nomenclature (- arg))
  601.   (c-keep-region-active))
  602.  
  603. (defun c-scope-operator ()
  604.   "Insert a double colon scope operator at point.
  605. No indentation or other \"electric\" behavior is performed."
  606.   (interactive "*")
  607.   (insert "::"))
  608.  
  609. (defun c-beginning-of-defun (&optional arg)
  610.   "Move backward to the beginning of a defun.
  611. With argument, do it that many times.  Negative arg -N
  612. means move forward to Nth following beginning of defun.
  613. Returns t unless search stops due to beginning or end of buffer.
  614.  
  615. Unlike the built-in `beginning-of-defun' this tries to be smarter
  616. about finding the char with open-parenthesis syntax that starts the
  617. defun."
  618.   (interactive "p")
  619.   (if (< arg 0)
  620.       (c-end-of-defun (- arg))
  621.     (while (> arg 0)
  622.       (let ((state (nreverse (c-parse-state)))
  623.         prevbod bod)
  624.     (while (and state (not bod))
  625.       (setq bod (car state)
  626.         state (cdr state))
  627.       (if (consp bod)
  628.           (setq prevbod (car bod)
  629.             bod nil)))
  630.     (cond
  631.      (bod (goto-char bod))
  632.      (prevbod (goto-char prevbod))
  633.      (t (goto-char (c-point 'bod)))))
  634.       (setq arg (1- arg))))
  635.   (c-keep-region-active))
  636.  
  637. (defun c-end-of-defun (&optional arg)
  638.   "Move forward to next end of defun.  With argument, do it that many times.
  639. Negative argument -N means move back to Nth preceding end of defun.
  640.  
  641. An end of a defun occurs right after the close-parenthesis that matches
  642. the open-parenthesis that starts a defun; see `beginning-of-defun'."
  643.   (interactive "p")
  644.   (if (< arg 0)
  645.       (c-beginning-of-defun (- arg))
  646.     (while (> arg 0)
  647.       ;; skip down into the next defun-block
  648.       (while (and (c-safe (down-list 1) t)
  649.           (not (eq (char-before) ?{)))
  650.     (forward-char -1)
  651.     (forward-sexp))
  652.       (c-beginning-of-defun 1)
  653.       (forward-sexp 1)
  654.       (setq arg (1- arg)))
  655.     (forward-line 1))
  656.   (c-keep-region-active))
  657.  
  658.  
  659. (defun c-beginning-of-statement (&optional count lim sentence-flag)
  660.   "Go to the beginning of the innermost C statement.
  661. With prefix arg, go back N - 1 statements.  If already at the
  662. beginning of a statement then go to the beginning of the closest
  663. preceding one, moving into nested blocks if necessary (use
  664. \\[backward-sexp] to skip over a block).  If within a comment, or next
  665. to a comment (only whitespace between), move by sentences instead of
  666. statements.
  667.  
  668. When called from a program, this function takes 3 optional args: the
  669. repetition count, a buffer position limit which is the farthest back
  670. to search, and a flag saying whether to do sentence motion when in a
  671. comment."
  672.   (interactive (list (prefix-numeric-value current-prefix-arg)
  673.              nil t))
  674.   (let* ((count (or count 1))
  675.      here
  676.      (range (c-collect-line-comments (c-literal-limits lim))))
  677.     (while (and (/= count 0)
  678.         (or (not lim) (> (point) lim)))
  679.       (setq here (point))
  680.       (if (and (not range) sentence-flag)
  681.       (save-excursion
  682.         ;; Find the comment next to point if we're not in one.
  683.         (if (> count 0)
  684.         ;; Finding a comment backwards is a bit cumbersome
  685.         ;; because `forward-comment' regards every newline as
  686.         ;; a comment when searching backwards (Emacs 19.34).
  687.         (while (and (progn (skip-chars-backward " \t")
  688.                    (setq range (point))
  689.                    (setq range (if (forward-comment -1)
  690.                            (cons (point) range)
  691.                          nil)))
  692.                 (= (char-after) ?\n)))
  693.           (skip-chars-forward " \t\n")
  694.           (setq range (point))
  695.           (setq range (if (forward-comment 1)
  696.                   (cons range (point))
  697.                 nil)))
  698.         (setq range (c-collect-line-comments range))))
  699.       (if (and (< count 0) (= here (point-max)))
  700.       ;; Special case because eob might be in a literal.
  701.       (setq range nil))
  702.       (if range
  703.       (if (and sentence-flag
  704.            (/= (char-syntax (char-after (car range))) ?\"))
  705.           (progn
  706.         ;; move by sentence, but not past the limit of the literal
  707.         (save-restriction
  708.           (narrow-to-region (save-excursion
  709.                       (goto-char (car range))
  710.                       (looking-at comment-start-skip)
  711.                       (goto-char (match-end 0))
  712.                       (point))
  713.                     (save-excursion
  714.                       (goto-char (cdr range))
  715.                       (if (save-excursion
  716.                         (goto-char (car range))
  717.                         (looking-at "/\\*"))
  718.                       (backward-char 2))
  719.                       (skip-chars-backward " \t\n")
  720.                       (point)))
  721.           (c-safe (forward-sentence (if (> count 0) -1 1))))
  722.         ;; See if we should escape the literal.
  723.         (if (> count 0)
  724.             (if (< (point) here)
  725.             (setq count (1- count))
  726.               (goto-char (car range))
  727.               (setq range nil))
  728.           (if (> (point) here)
  729.               (setq count (1+ count))
  730.             (goto-char (cdr range))
  731.             (setq range nil))))
  732.         (goto-char (if (> count 0) (car range) (cdr range)))
  733.         (setq range nil))
  734.     ;; Below we do approximately the same as
  735.     ;; c-beginning-of-statement-1 and c-end-of-statement-1 and
  736.     ;; perhaps they should be changed, but that'd likely break a
  737.     ;; lot in cc-engine.
  738.     (goto-char here)
  739.     ;; Move out of any enclosing non-`{ }' parens.
  740.     (let ((last (point)))
  741.       (while (and (c-safe (progn (up-list 1) t))
  742.               (/= (char-before) ?\}))
  743.         (setq last (point)))
  744.       (goto-char last))
  745.     (if (> count 0)
  746.         (if (condition-case nil
  747.             ;; Stop before `{' and after `;', `{', `}' and
  748.             ;; `};' when not followed by `}', but on the other
  749.             ;; side of the syntactic ws.  Also stop before
  750.             ;; `}', but only to catch comments.  Move by sexps
  751.             ;; and move into `{ }', but not into any other
  752.             ;; other type of paren.
  753.             (catch 'done
  754.               (let (last)
  755.             (while t
  756.               (setq last (point))
  757.               (if (and (looking-at "[{}]")
  758.                    (/= here last))
  759.                   (throw 'done (= (char-after) ?{)))
  760.               (c-backward-syntactic-ws)
  761.               (cond ((bobp) ; Must handle bob specially.
  762.                  (if (= here last)
  763.                      (if (= last (point-min))
  764.                      (throw 'done t)
  765.                        (goto-char last)
  766.                        (throw 'done nil))
  767.                    (goto-char last)
  768.                    (throw 'done t)))
  769.                 ((progn (backward-char)
  770.                     (looking-at "[;{}]"))
  771.                  (if (or (= here last)
  772.                      (= (char-after last) ?}))
  773.                      (if (and (= (char-before) ?})
  774.                           (= (char-after) ?\;))
  775.                      (backward-char))
  776.                    (goto-char last)
  777.                    (throw 'done t)))
  778.                 ((or (= (char-syntax (char-after)) ?\))
  779.                      (= (char-syntax (char-after)) ?\"))
  780.                  (forward-char)
  781.                  (backward-sexp))
  782.                 ))))
  783.           (error
  784.            (goto-char (point-min))
  785.            t))
  786.         (setq count (1- count)))
  787.       (if (condition-case nil
  788.           ;; Stop before `{' and `}' and after `;', `}' and
  789.           ;; `};'.  Also stop after `{', but only to catch
  790.           ;; comments.  Move by sexps and move into `{ }', but
  791.           ;; not into any other other type of paren.
  792.           (catch 'done
  793.             (let (last)
  794.               (while t
  795.             (setq last (point))
  796.             (c-forward-syntactic-ws)
  797.             (cond ((= (char-after) ?{)
  798.                    (if (= here last)
  799.                    (progn (forward-char)
  800.                       (throw 'done nil))
  801.                  (goto-char last)
  802.                  (throw 'done t)))
  803.                   ((and (= (char-after) ?})
  804.                     (/= here last))
  805.                    (goto-char last)
  806.                    (throw 'done t))
  807.                   ((looking-at ";\\|};?")
  808.                    (goto-char (match-end 0))
  809.                    (throw 'done t))
  810.                   ((or (= (char-syntax (char-after)) ?\()
  811.                    (= (char-syntax (char-after)) ?\"))
  812.                    (forward-sexp))
  813.                   (t
  814.                    (forward-char))
  815.                   ))))
  816.         (error
  817.          (goto-char (point-max))
  818.          t))
  819.           (setq count (1+ count)))))
  820.       ;; If we haven't moved we're near a buffer limit.
  821.       (when (= (point) here)
  822.     (goto-char (if (> count 0) (point-min) (point-max)))
  823.     (setq count 0)))
  824.     ;; its possible we've been left up-buf of lim
  825.     (if lim (goto-char (max (point) lim))))
  826.   (c-keep-region-active))
  827.  
  828. (defun c-end-of-statement (&optional count lim sentence-flag)
  829.   "Go to the end of the innermost C statement.
  830. With prefix arg, go forward N - 1 statements.  Move forward to the end
  831. of the next statement if already at end, and move into nested blocks
  832. \(use \\[forward-sexp] to skip over a block).  If within a comment, or
  833. next to a comment (only whitespace between), move by sentences instead
  834. of statements.
  835.  
  836. When called from a program, this function takes 3 optional args: the
  837. repetition count, a buffer position limit which is the farthest back
  838. to search, and a flag saying whether to do sentence motion when in a
  839. comment."
  840.   (interactive (list (prefix-numeric-value current-prefix-arg)
  841.              nil t))
  842.   (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
  843.   (c-keep-region-active))
  844.  
  845.  
  846. ;; set up electric character functions to work with pending-del,
  847. ;; (a.k.a. delsel) mode.  All symbols get the t value except
  848. ;; the functions which delete, which gets 'supersede.
  849. (mapcar
  850.  (function
  851.   (lambda (sym)
  852.     (put sym 'delete-selection t)    ; for delsel (Emacs)
  853.     (put sym 'pending-delete t)))    ; for pending-del (XEmacs)
  854.  '(c-electric-pound
  855.    c-electric-brace
  856.    c-electric-slash
  857.    c-electric-star
  858.    c-electric-semi&comma
  859.    c-electric-lt-gt
  860.    c-electric-colon))
  861. (put 'c-electric-delete    'delete-selection 'supersede) ; delsel
  862. (put 'c-electric-delete    'pending-delete   'supersede) ; pending-del
  863. (put 'c-electric-backspace 'delete-selection 'supersede) ; delsel
  864. (put 'c-electric-backspace 'pending-delete   'supersede) ; pending-del
  865.  
  866.  
  867. ;; This is used by indent-for-comment to decide how much to indent a
  868. ;; comment in C code based on its context.
  869. (defun c-comment-indent ()
  870.   (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
  871.       0                ;Existing comment at bol stays there.
  872.     (let ((opoint (point))
  873.       placeholder)
  874.       (save-excursion
  875.     (beginning-of-line)
  876.     (cond
  877.      ;; CASE 1: A comment following a solitary close-brace should
  878.      ;; have only one space.
  879.      ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
  880.                   c-comment-start-regexp
  881.                   "\\)"))
  882.       (search-forward "}")
  883.       (1+ (current-column)))
  884.      ;; CASE 2: 2 spaces after #endif
  885.      ((or (looking-at "^#[ \t]*endif[ \t]*")
  886.           (looking-at "^#[ \t]*else[ \t]*"))
  887.       7)
  888.      ;; CASE 3: when comment-column is nil, calculate the offset
  889.      ;; according to c-offsets-alist.  E.g. identical to hitting
  890.      ;; TAB.
  891.      ((and c-indent-comments-syntactically-p
  892.            (save-excursion
  893.          (skip-chars-forward " \t")
  894.          (or (looking-at comment-start)
  895.              (eolp))))
  896.       (let ((syntax (c-guess-basic-syntax)))
  897.         ;; BOGOSITY ALERT: if we're looking at the eol, its
  898.         ;; because indent-for-comment hasn't put the comment-start
  899.         ;; in the buffer yet.  this will screw up the syntactic
  900.         ;; analysis so we kludge in the necessary info.  Another
  901.         ;; kludge is that if we're at the bol, then we really want
  902.         ;; to ignore any anchoring as specified by
  903.         ;; c-comment-only-line-offset since it doesn't apply here.
  904.         (if (save-excursion
  905.           (beginning-of-line)
  906.           (skip-chars-forward " \t")
  907.           (eolp))
  908.         (c-add-syntax 'comment-intro))
  909.         (let ((c-comment-only-line-offset
  910.            (if (consp c-comment-only-line-offset)
  911.                c-comment-only-line-offset
  912.              (cons c-comment-only-line-offset
  913.                c-comment-only-line-offset))))
  914.           (apply '+ (mapcar 'c-get-offset syntax)))))
  915.      ;; CASE 4: use comment-column if previous line is a
  916.      ;; comment-only line indented to the left of comment-column
  917.      ((save-excursion
  918.         (beginning-of-line)
  919.         (and (not (bobp))
  920.          (forward-line -1))
  921.         (skip-chars-forward " \t")
  922.         (prog1
  923.         (looking-at c-comment-start-regexp)
  924.           (setq placeholder (point))))
  925.       (goto-char placeholder)
  926.       (if (< (current-column) comment-column)
  927.           comment-column
  928.         (current-column)))
  929.      ;; CASE 5: If comment-column is 0, and nothing but space
  930.      ;; before the comment, align it at 0 rather than 1.
  931.      ((progn
  932.         (goto-char opoint)
  933.         (skip-chars-backward " \t")
  934.         (and (= comment-column 0) (bolp)))
  935.       0)
  936.      ;; CASE 6: indent at comment column except leave at least one
  937.      ;; space.
  938.      (t (max (1+ (current-column))
  939.          comment-column))
  940.      )))))
  941.  
  942.  
  943. ;; for proposed new variable comment-line-break-function
  944. (defun c-comment-line-break-function (&optional soft)
  945.   ;; we currently don't do anything with soft line breaks
  946.   (let ((literal (c-in-literal))
  947.     at-comment-col)
  948.     (cond
  949.      ((eq literal 'string))
  950.      ((or (not c-comment-continuation-stars)
  951.       (not literal))
  952.       (indent-new-comment-line soft))
  953.      (t (let ((here (point))
  954.           (leader c-comment-continuation-stars))
  955.       (back-to-indentation)
  956.       ;; comment could be hanging
  957.       (if (not (c-in-literal))
  958.           (progn
  959.         (forward-line 1)
  960.         (forward-comment -1)
  961.         (setq at-comment-col (= (current-column) comment-column))))
  962.       ;; are we looking at a block or lines style comment?
  963.       (if (and (looking-at (concat "\\(" c-comment-start-regexp
  964.                        "\\)[ \t]+"))
  965.            (string-equal (match-string 1) "//"))
  966.           ;; line style
  967.           (setq leader (match-string 0)))
  968.       (goto-char here)
  969.       (delete-region (progn (skip-chars-backward " \t") (point))
  970.              (progn (skip-chars-forward " \t") (point)))
  971.       (newline)
  972.       ;; to avoid having an anchored comment that c-indent-line will
  973.       ;; trip up on
  974.       (insert " " leader)
  975.       (if at-comment-col
  976.           (indent-for-comment))
  977.       (c-indent-line))))))
  978.  
  979. ;; advice for indent-new-comment-line for older Emacsen
  980. (if (boundp 'comment-line-break-function)
  981.     nil
  982.   (require 'advice)
  983.   (defadvice indent-new-comment-line (around c-line-break-advice activate)
  984.     (if (or (not c-buffer-is-cc-mode)
  985.         (not (c-in-literal))
  986.         (not c-comment-continuation-stars))
  987.     ad-do-it
  988.       (c-comment-line-break-function (ad-get-arg 0)))))
  989.  
  990. ;; used by outline-minor-mode
  991. (defun c-outline-level ()
  992.   (save-excursion
  993.     (skip-chars-forward "\t ")
  994.     (current-column)))
  995.  
  996.  
  997. (defun c-up-conditional (count)
  998.   "Move back to the containing preprocessor conditional, leaving mark behind.
  999. A prefix argument acts as a repeat count.  With a negative argument,
  1000. move forward to the end of the containing preprocessor conditional.
  1001. When going backwards, `#elif' is treated like `#else' followed by
  1002. `#if'.  When going forwards, `#elif' is ignored."
  1003.   (interactive "p")
  1004.   (c-forward-conditional (- count) t)
  1005.   (c-keep-region-active))
  1006.  
  1007. (defun c-backward-conditional (count &optional up-flag)
  1008.   "Move back across a preprocessor conditional, leaving mark behind.
  1009. A prefix argument acts as a repeat count.  With a negative argument,
  1010. move forward across a preprocessor conditional."
  1011.   (interactive "p")
  1012.   (c-forward-conditional (- count) up-flag)
  1013.   (c-keep-region-active))
  1014.  
  1015. (defun c-forward-conditional (count &optional up-flag)
  1016.   "Move forward across a preprocessor conditional, leaving mark behind.
  1017. A prefix argument acts as a repeat count.  With a negative argument,
  1018. move backward across a preprocessor conditional."
  1019.   (interactive "p")
  1020.   (let* ((forward (> count 0))
  1021.      (increment (if forward -1 1))
  1022.      (search-function (if forward 're-search-forward 're-search-backward))
  1023.      (new))
  1024.     (save-excursion
  1025.       (while (/= count 0)
  1026.     (let ((depth (if up-flag 0 -1)) found)
  1027.       (save-excursion
  1028.         ;; Find the "next" significant line in the proper direction.
  1029.         (while (and (not found)
  1030.             ;; Rather than searching for a # sign that
  1031.             ;; comes at the beginning of a line aside from
  1032.             ;; whitespace, search first for a string
  1033.             ;; starting with # sign.  Then verify what
  1034.             ;; precedes it.  This is faster on account of
  1035.             ;; the fastmap feature of the regexp matcher.
  1036.             (funcall search-function
  1037.                  "#[ \t]*\\(if\\|elif\\|endif\\)"
  1038.                  nil t))
  1039.           (beginning-of-line)
  1040.           ;; Now verify it is really a preproc line.
  1041.           (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
  1042.           (let ((prev depth))
  1043.             ;; Update depth according to what we found.
  1044.             (beginning-of-line)
  1045.             (cond ((looking-at "[ \t]*#[ \t]*endif")
  1046.                (setq depth (+ depth increment)))
  1047.               ((looking-at "[ \t]*#[ \t]*elif")
  1048.                (if (and forward (= depth 0))
  1049.                    (setq found (point))))
  1050.               (t (setq depth (- depth increment))))
  1051.             ;; If we are trying to move across, and we find an
  1052.             ;; end before we find a beginning, get an error.
  1053.             (if (and (< prev 0) (< depth prev))
  1054.             (error (if forward
  1055.                    "No following conditional at this level"
  1056.                  "No previous conditional at this level")))
  1057.             ;; When searching forward, start from next line so
  1058.             ;; that we don't find the same line again.
  1059.             (if forward (forward-line 1))
  1060.             ;; If this line exits a level of conditional, exit
  1061.             ;; inner loop.
  1062.             (if (< depth 0)
  1063.             (setq found (point))))
  1064.         ;; else
  1065.         (if forward (forward-line 1))
  1066.         )))
  1067.       (or found
  1068.           (error "No containing preprocessor conditional"))
  1069.       (goto-char (setq new found)))
  1070.     (setq count (+ count increment))))
  1071.     (push-mark)
  1072.     (goto-char new))
  1073.   (c-keep-region-active))
  1074.  
  1075.  
  1076. ;; commands to indent lines, regions, defuns, and expressions
  1077. (defun c-indent-command (&optional whole-exp)
  1078.   "Indent current line as C code, and/or insert some whitespace.
  1079.  
  1080. If `c-tab-always-indent' is t, always just indent the current line.
  1081. If nil, indent the current line only if point is at the left margin or
  1082. in the line's indentation; otherwise insert some whitespace[*].  If
  1083. other than nil or t, then some whitespace[*] is inserted only within
  1084. literals (comments and strings) and inside preprocessor directives,
  1085. but the line is always reindented.
  1086.  
  1087. A numeric argument, regardless of its value, means indent rigidly all
  1088. the lines of the expression starting after point so that this line
  1089. becomes properly indented.  The relative indentation among the lines
  1090. of the expression are preserved.
  1091.  
  1092.   [*] The amount and kind of whitespace inserted is controlled by the
  1093.   variable `c-insert-tab-function', which is called to do the actual
  1094.   insertion of whitespace.  Normally the function in this variable
  1095.   just inserts a tab character, or the equivalent number of spaces,
  1096.   depending on the variable `indent-tabs-mode'."
  1097.  
  1098.   (interactive "*P")
  1099.   (let ((bod (c-point 'bod)))
  1100.     (if whole-exp
  1101.     ;; If arg, always indent this line as C
  1102.     ;; and shift remaining lines of expression the same amount.
  1103.     (let ((shift-amt (c-indent-line))
  1104.           beg end)
  1105.       (save-excursion
  1106.         (if (eq c-tab-always-indent t)
  1107.         (beginning-of-line))
  1108.         (setq beg (point))
  1109.         (forward-sexp 1)
  1110.         (setq end (point))
  1111.         (goto-char beg)
  1112.         (forward-line 1)
  1113.         (setq beg (point)))
  1114.       (if (> end beg)
  1115.           (indent-code-rigidly beg end (- shift-amt) "#")))
  1116.       ;; No arg supplied, use c-tab-always-indent to determine
  1117.       ;; behavior
  1118.       (cond
  1119.        ;; CASE 1: indent when at column zero or in lines indentation,
  1120.        ;; otherwise insert a tab
  1121.        ((not c-tab-always-indent)
  1122.     (if (save-excursion
  1123.           (skip-chars-backward " \t")
  1124.           (not (bolp)))
  1125.         (funcall c-insert-tab-function)
  1126.       (c-indent-line)))
  1127.        ;; CASE 2: just indent the line
  1128.        ((eq c-tab-always-indent t)
  1129.     (c-indent-line))
  1130.        ;; CASE 3: if in a literal, insert a tab, but always indent the
  1131.        ;; line
  1132.        (t
  1133.     (if (c-in-literal bod)
  1134.         (funcall c-insert-tab-function))
  1135.     (c-indent-line)
  1136.     )))))
  1137.  
  1138. (defun c-indent-exp (&optional shutup-p)
  1139.   "Indent each line in balanced expression following point.
  1140. Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
  1141.   (interactive "*P")
  1142.   (let ((here (point))
  1143.     end progress-p)
  1144.     (unwind-protect
  1145.     (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
  1146.           (start (progn
  1147.                ;; try to be smarter about finding the range of
  1148.                ;; lines to indent. skip all following
  1149.                ;; whitespace. failing that, try to find any
  1150.                ;; opening brace on the current line
  1151.                (skip-chars-forward " \t\n")
  1152.                (if (memq (char-after) '(?\( ?\[ ?\{))
  1153.                (point)
  1154.              (let ((state (parse-partial-sexp (point)
  1155.                               (c-point 'eol))))
  1156.                (and (nth 1 state)
  1157.                 (goto-char (nth 1 state))
  1158.                 (memq (char-after) '(?\( ?\[ ?\{))
  1159.                 (point)))))))
  1160.       ;; find balanced expression end
  1161.       (setq end (and (c-safe (progn (forward-sexp 1) t))
  1162.              (point-marker)))
  1163.       ;; sanity check
  1164.       (and (not start)
  1165.            (not shutup-p)
  1166.            (error "Cannot find start of balanced expression to indent."))
  1167.       (and (not end)
  1168.            (not shutup-p)
  1169.            (error "Cannot find end of balanced expression to indent."))
  1170.       (c-progress-init start end 'c-indent-exp)
  1171.       (setq progress-p t)
  1172.       (goto-char start)
  1173.       (beginning-of-line)
  1174.       (while (< (point) end)
  1175.         (if (not (looking-at "[ \t]*$"))
  1176.         (c-indent-line))
  1177.         (c-progress-update)
  1178.         (forward-line 1)))
  1179.       ;; make sure marker is deleted
  1180.       (and end
  1181.        (set-marker end nil))
  1182.       (and progress-p
  1183.        (c-progress-fini 'c-indent-exp))
  1184.       (goto-char here))))
  1185.  
  1186. (defun c-indent-defun ()
  1187.   "Re-indents the current top-level function def, struct or class declaration."
  1188.   (interactive "*")
  1189.   (let ((here (point-marker))
  1190.     (c-echo-syntactic-information-p nil)
  1191.     (brace (c-least-enclosing-brace (c-parse-state))))
  1192.     (goto-char (or brace (c-point 'bod)))
  1193.     ;; if we're sitting at b-o-b, it might be because there was no
  1194.     ;; least enclosing brace and we were sitting on the defun's open
  1195.     ;; brace.
  1196.     (if (and (bobp) (not (eq (char-after) ?\{)))
  1197.     (goto-char here))
  1198.     ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
  1199.     ;; the open brace. I consider this an Emacs bug.
  1200.     (and (boundp 'defun-prompt-regexp)
  1201.      defun-prompt-regexp
  1202.      (looking-at defun-prompt-regexp)
  1203.      (goto-char (match-end 0)))
  1204.     ;; catch all errors in c-indent-exp so we can 1. give more
  1205.     ;; meaningful error message, and 2. restore point
  1206.     (unwind-protect
  1207.     (c-indent-exp)
  1208.       (goto-char here)
  1209.       (set-marker here nil))))
  1210.  
  1211. (defun c-indent-region (start end)
  1212.   ;; Indent every line whose first char is between START and END inclusive.
  1213.   (save-excursion
  1214.     (goto-char start)
  1215.     ;; Advance to first nonblank line.
  1216.     (skip-chars-forward " \t\n")
  1217.     (beginning-of-line)
  1218.     (let (endmark)
  1219.       (unwind-protect
  1220.       (let ((c-tab-always-indent t)
  1221.         ;; shut up any echo msgs on indiv lines
  1222.         (c-echo-syntactic-information-p nil)
  1223.         fence)
  1224.         (c-progress-init start end 'c-indent-region)
  1225.         (setq endmark (copy-marker end))
  1226.         (while (and (bolp)
  1227.             (not (eobp))
  1228.             (< (point) endmark))
  1229.           ;; update progress
  1230.           (c-progress-update)
  1231.           ;; Indent one line as with TAB.
  1232.           (let (nextline sexpend sexpbeg)
  1233.         ;; skip blank lines
  1234.         (skip-chars-forward " \t\n")
  1235.         (beginning-of-line)
  1236.         ;; indent the current line
  1237.         (c-indent-line)
  1238.         (setq fence (point))
  1239.         (if (save-excursion
  1240.               (beginning-of-line)
  1241.               (looking-at "[ \t]*#"))
  1242.             (forward-line 1)
  1243.           (save-excursion
  1244.             ;; Find beginning of following line.
  1245.             (setq nextline (c-point 'bonl))
  1246.             ;; Find first beginning-of-sexp for sexp extending past
  1247.             ;; this line.
  1248.             (beginning-of-line)
  1249.             (while (< (point) nextline)
  1250.               (condition-case nil
  1251.               (progn
  1252.                 (forward-sexp 1)
  1253.                 (setq sexpend (point)))
  1254.             (error (setq sexpend nil)
  1255.                    (goto-char nextline)))
  1256.               (c-forward-syntactic-ws))
  1257.             (if sexpend
  1258.             (progn 
  1259.               ;; make sure the sexp we found really starts on the
  1260.               ;; current line and extends past it
  1261.               (goto-char sexpend)
  1262.               (setq sexpend (point-marker))
  1263.               (c-safe (backward-sexp 1))
  1264.               (setq sexpbeg (point))))
  1265.             (if (and sexpbeg (< sexpbeg fence))
  1266.             (setq sexpbeg fence)))
  1267.           ;; check to see if the next line starts a
  1268.           ;; comment-only line
  1269.           (save-excursion
  1270.             (forward-line 1)
  1271.             (skip-chars-forward " \t")
  1272.             (if (looking-at c-comment-start-regexp)
  1273.             (setq sexpbeg (c-point 'bol))))
  1274.           ;; If that sexp ends within the region, indent it all at
  1275.           ;; once, fast.
  1276.           (condition-case nil
  1277.               (if (and sexpend
  1278.                    (> sexpend nextline)
  1279.                    (<= sexpend endmark))
  1280.               (progn
  1281.                 (goto-char sexpbeg)
  1282.                 (c-indent-exp 'shutup)
  1283.                 (c-progress-update)
  1284.                 (goto-char sexpend)))
  1285.             (error
  1286.              (goto-char sexpbeg)
  1287.              (c-indent-line)))
  1288.           ;; Move to following line and try again.
  1289.           (and sexpend
  1290.                (markerp sexpend)
  1291.                (set-marker sexpend nil))
  1292.           (forward-line 1)
  1293.           (setq fence (point))))))
  1294.     (set-marker endmark nil)
  1295.     (c-progress-fini 'c-indent-region)
  1296.     (c-echo-parsing-error)
  1297.     ))))
  1298.  
  1299. (defun c-mark-function ()
  1300.   "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
  1301.   (interactive)
  1302.   (let ((here (point))
  1303.     ;; there should be a c-point position for 'eod
  1304.     (eod  (save-excursion (end-of-defun) (point)))
  1305.     (state (c-parse-state))
  1306.     brace)
  1307.     (while state
  1308.       (setq brace (car state))
  1309.       (if (consp brace)
  1310.       (goto-char (cdr brace))
  1311.     (goto-char brace))
  1312.       (setq state (cdr state)))
  1313.     (if (eq (char-after) ?{)
  1314.     (progn
  1315.       (forward-line -1)
  1316.       (while (not (or (bobp)
  1317.               (looking-at "[ \t]*$")))
  1318.         (forward-line -1)))
  1319.       (forward-line 1)
  1320.       (skip-chars-forward " \t\n"))
  1321.     (push-mark here)
  1322.     (push-mark eod nil t)))
  1323.  
  1324.  
  1325. ;; for progress reporting
  1326. (defvar c-progress-info nil)
  1327.  
  1328. (defun c-progress-init (start end context)
  1329.   (cond
  1330.    ;; Be silent
  1331.    ((not c-progress-interval))
  1332.    ;; Start the progress update messages.  If this Emacs doesn't have
  1333.    ;; a built-in timer, just be dumb about it.
  1334.    ((not (fboundp 'current-time))
  1335.     (message "indenting region... (this may take a while)"))
  1336.    ;; If progress has already been initialized, do nothing. otherwise
  1337.    ;; initialize the counter with a vector of:
  1338.    ;;     [start end lastsec context]
  1339.    (c-progress-info)
  1340.    (t (setq c-progress-info (vector start
  1341.                     (save-excursion
  1342.                       (goto-char end)
  1343.                       (point-marker))
  1344.                     (nth 1 (current-time))
  1345.                     context))
  1346.       (message "indenting region..."))
  1347.    ))
  1348.  
  1349. (defun c-progress-update ()
  1350.   ;; update progress
  1351.   (if (not (and c-progress-info c-progress-interval))
  1352.       nil
  1353.     (let ((now (nth 1 (current-time)))
  1354.       (start (aref c-progress-info 0))
  1355.       (end (aref c-progress-info 1))
  1356.       (lastsecs (aref c-progress-info 2)))
  1357.       ;; should we update?  currently, update happens every 2 seconds,
  1358.       ;; what's the right value?
  1359.       (if (< c-progress-interval (- now lastsecs))
  1360.       (progn
  1361.         (message "indenting region... (%d%% complete)"
  1362.              (/ (* 100 (- (point) start)) (- end start)))
  1363.         (aset c-progress-info 2 now)))
  1364.       )))
  1365.  
  1366. (defun c-progress-fini (context)
  1367.   ;; finished
  1368.   (if (not c-progress-interval)
  1369.       nil
  1370.     (if (or (eq context (aref c-progress-info 3))
  1371.         (eq context t))
  1372.     (progn
  1373.       (set-marker (aref c-progress-info 1) nil)
  1374.       (setq c-progress-info nil)
  1375.       (message "indenting region...done")))))
  1376.  
  1377.  
  1378.  
  1379. ;;; This page handles insertion and removal of backslashes for C macros.
  1380.  
  1381. (defun c-backslash-region (from to delete-flag)
  1382.   "Insert, align, or delete end-of-line backslashes on the lines in the region.
  1383. With no argument, inserts backslashes and aligns existing backslashes.
  1384. With an argument, deletes the backslashes.
  1385.  
  1386. This function does not modify blank lines at the start of the region.
  1387. If the region ends at the start of a line, it always deletes the
  1388. backslash (if any) at the end of the previous line.
  1389.  
  1390. You can put the region around an entire macro definition and use this
  1391. command to conveniently insert and align the necessary backslashes."
  1392.   (interactive "*r\nP")
  1393.   (save-excursion
  1394.     (goto-char from)
  1395.     (let ((column c-backslash-column)
  1396.           (endmark (make-marker)))
  1397.       (move-marker endmark to)
  1398.       ;; Compute the smallest column number past the ends of all the lines.
  1399.       (if (not delete-flag)
  1400.           (while (< (point) to)
  1401.             (end-of-line)
  1402.             (if (eq (char-before) ?\\)
  1403.                 (progn (forward-char -1)
  1404.                        (skip-chars-backward " \t")))
  1405.             (setq column (max column (1+ (current-column))))
  1406.             (forward-line 1)))
  1407.       ;; Adjust upward to a tab column, if that doesn't push past the margin.
  1408.       (if (> (% column tab-width) 0)
  1409.           (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
  1410.             (if (< adjusted (window-width))
  1411.                 (setq column adjusted))))
  1412.       ;; Don't modify blank lines at start of region.
  1413.       (goto-char from)
  1414.       (while (and (< (point) endmark) (eolp))
  1415.         (forward-line 1))
  1416.       ;; Add or remove backslashes on all the lines.
  1417.       (while (< (point) endmark)
  1418.     (if (and (not delete-flag)
  1419.           ;; Un-backslashify the last line
  1420.           ;; if the region ends right at the start of the next line.
  1421.           (save-excursion
  1422.             (forward-line 1)
  1423.             (< (point) endmark)))
  1424.             (c-append-backslash column)
  1425.           (c-delete-backslash))
  1426.         (forward-line 1))
  1427.       (move-marker endmark nil))))
  1428.  
  1429. (defun c-append-backslash (column)
  1430.   (end-of-line)
  1431.   (if (eq (char-before) ?\\)
  1432.       (progn (forward-char -1)
  1433.              (delete-horizontal-space)
  1434.              (indent-to column))
  1435.     (indent-to column)
  1436.     (insert "\\")))
  1437.  
  1438. (defun c-delete-backslash ()
  1439.   (end-of-line)
  1440.   (or (bolp)
  1441.       (progn
  1442.      (forward-char -1)
  1443.      (if (looking-at "\\\\")
  1444.          (delete-region (1+ (point))
  1445.                 (progn (skip-chars-backward " \t") (point)))))))
  1446.  
  1447.  
  1448. (defun c-fill-paragraph (&optional arg)
  1449.   "Like \\[fill-paragraph] but handles C and C++ style comments.
  1450. If any of the current line is a comment or within a comment,
  1451. fill the comment or the paragraph of it that point is in,
  1452. preserving the comment indentation or line-starting decorations.
  1453.  
  1454. Optional prefix ARG means justify paragraph as well."
  1455.   (interactive "*P")
  1456.   (let* (comment-start-place
  1457.      (first-line
  1458.       ;; Check for obvious entry to comment.
  1459.       (save-excursion
  1460.         (beginning-of-line)
  1461.         (skip-chars-forward " \t\n")
  1462.         (and (looking-at comment-start-skip)
  1463.          (setq comment-start-place (point)))))
  1464.      (re1 "\\|[ \t]*/\\*[ \t]*$\\|[ \t]*\\*/[ \t]*$\\|[ \t/*]*$"))
  1465.     (if (save-excursion
  1466.       (beginning-of-line)
  1467.       (looking-at ".*//"))
  1468.     (let ((fill-prefix fill-prefix)
  1469.            ;; Lines containing just a comment start or just an end
  1470.            ;; should not be filled into paragraphs they are next
  1471.            ;; to.
  1472.           (paragraph-start (concat paragraph-start re1))
  1473.           (paragraph-separate (concat paragraph-separate re1)))
  1474.       (save-excursion
  1475.         (beginning-of-line)
  1476.         ;; Move up to first line of this comment.
  1477.         (while (and (not (bobp))
  1478.              (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
  1479.           (forward-line -1))
  1480.          (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
  1481.         (forward-line 1))
  1482.         ;; Find the comment start in this line.
  1483.         (re-search-forward "[ \t]*//[ \t]*")
  1484.         ;; Set the fill-prefix to be what all lines except the first
  1485.         ;; should start with.  But do not alter a user set fill-prefix.
  1486.         (if (null fill-prefix)
  1487.         (setq fill-prefix (buffer-substring (match-beginning 0)
  1488.                             (match-end 0))))
  1489.         (save-restriction
  1490.           ;; Narrow down to just the lines of this comment.
  1491.           (narrow-to-region (c-point 'bol)
  1492.                 (save-excursion
  1493.                   (forward-line 1)
  1494.                   (while 
  1495.                       (looking-at (regexp-quote fill-prefix))
  1496.                     (forward-line 1))
  1497.                   (point)))
  1498.           (fill-paragraph arg)
  1499.           t)))
  1500.       ;; else C style comments
  1501.       (if (or first-line
  1502.           ;; t if we enter a comment between start of function and
  1503.           ;; this line.
  1504.           (eq (c-in-literal) 'c)
  1505.           ;; t if this line contains a comment starter.
  1506.           (setq first-line
  1507.             (save-excursion
  1508.               (beginning-of-line)
  1509.               (prog1
  1510.               (re-search-forward comment-start-skip
  1511.                          (save-excursion (end-of-line)
  1512.                                  (point))
  1513.                          t)
  1514.             (setq comment-start-place (point))))))
  1515.       ;; Inside a comment: fill one comment paragraph.
  1516.       (let ((fill-prefix
  1517.          ;; The prefix for each line of this paragraph
  1518.          ;; is the appropriate part of the start of this line,
  1519.          ;; up to the column at which text should be indented.
  1520.          (save-excursion
  1521.            (beginning-of-line)
  1522.            (if (looking-at "[ \t]*/\\*.*\\*/")
  1523.                (progn (re-search-forward comment-start-skip)
  1524.                   (make-string (current-column) ?\ ))
  1525.              (if first-line (forward-line 1))
  1526.  
  1527.              (let ((line-width (progn (end-of-line) (current-column))))
  1528.                (beginning-of-line)
  1529.                (prog1
  1530.                (buffer-substring
  1531.                 (point)
  1532.  
  1533.                 ;; How shall we decide where the end of the
  1534.                 ;; fill-prefix is?
  1535.                 (progn
  1536.                   (beginning-of-line)
  1537.                   (skip-chars-forward " \t*" (c-point 'eol))
  1538.                   ;; kludge alert, watch out for */, in
  1539.                   ;; which case fill-prefix should *not*
  1540.                   ;; be "*"!
  1541.                   (if (and (eq (char-after) ?/)
  1542.                        (eq (char-before) ?*))
  1543.                   (forward-char -1))
  1544.                   (point)))
  1545.  
  1546.              ;; If the comment is only one line followed
  1547.              ;; by a blank line, calling move-to-column
  1548.              ;; above may have added some spaces and tabs
  1549.              ;; to the end of the line; the fill-paragraph
  1550.              ;; function will then delete it and the
  1551.              ;; newline following it, so we'll lose a
  1552.              ;; blank line when we shouldn't.  So delete
  1553.              ;; anything move-to-column added to the end
  1554.              ;; of the line.  We record the line width
  1555.              ;; instead of the position of the old line
  1556.              ;; end because move-to-column might break a
  1557.              ;; tab into spaces, and the new characters
  1558.              ;; introduced there shouldn't be deleted.
  1559.  
  1560.              ;; If you can see a better way to do this,
  1561.              ;; please make the change.  This seems very
  1562.              ;; messy to me.
  1563.              (delete-region (progn (move-to-column line-width)
  1564.                            (point))
  1565.                     (progn (end-of-line) (point))))))))
  1566.  
  1567.         ;; Lines containing just a comment start or just an end
  1568.         ;; should not be filled into paragraphs they are next
  1569.         ;; to.
  1570.         (paragraph-start (concat paragraph-start re1))
  1571.         (paragraph-separate (concat paragraph-separate re1))
  1572.         (chars-to-delete 0)
  1573.         )
  1574.         (save-restriction
  1575.           ;; Don't fill the comment together with the code
  1576.           ;; following it.  So temporarily exclude everything
  1577.           ;; before the comment start, and everything after the
  1578.           ;; line where the comment ends.  If comment-start-place
  1579.           ;; is non-nil, the comment starter is there.  Otherwise,
  1580.           ;; point is inside the comment.
  1581.           (narrow-to-region (save-excursion
  1582.                   (if comment-start-place
  1583.                       (goto-char comment-start-place)
  1584.                     (search-backward "/*"))
  1585.                   (if (and (not c-hanging-comment-starter-p)
  1586.                        (looking-at
  1587.                         (concat c-comment-start-regexp
  1588.                             "[ \t]*$")))
  1589.                       (forward-line 1))
  1590.                   ;; Protect text before the comment
  1591.                   ;; start by excluding it.  Add
  1592.                   ;; spaces to bring back proper
  1593.                   ;; indentation of that point.
  1594.                   (let ((column (current-column)))
  1595.                     (prog1 (point)
  1596.                       (setq chars-to-delete column)
  1597.                       (insert-char ?\  column))))
  1598.                 (save-excursion
  1599.                   (if comment-start-place
  1600.                       (goto-char (+ comment-start-place 2)))
  1601.                   (search-forward "*/" nil 'move)
  1602.                   (forward-line 1)
  1603.                   (point)))
  1604.           (fill-paragraph arg)
  1605.           (save-excursion
  1606.         ;; Delete the chars we inserted to avoid clobbering
  1607.         ;; the stuff before the comment start.
  1608.         (goto-char (point-min))
  1609.         (if (> chars-to-delete 0)
  1610.             (delete-region (point) (+ (point) chars-to-delete)))
  1611.         ;; Find the comment ender (should be on last line of
  1612.         ;; buffer, given the narrowing) and don't leave it on
  1613.         ;; its own line, unless that's the style that's desired.
  1614.         (goto-char (point-max))
  1615.         (forward-line -1)
  1616.         (search-forward "*/" nil 'move)
  1617.         (beginning-of-line)
  1618.         (if (and c-hanging-comment-ender-p
  1619.              (looking-at "[ \t]*\\*/"))
  1620.             ;(delete-indentation)))))
  1621.             (let ((fill-column (+ fill-column 9999)))
  1622.               (forward-line -1)
  1623.               (fill-region-as-paragraph (point) (point-max))))))
  1624.         t)))))
  1625.  
  1626.  
  1627. (provide 'cc-cmds)
  1628. ;;; cc-cmds.el ends here
  1629.